package function

import (
	"github.com/dgrijalva/jwt-go"
	. "go_tempate/common/struct"
	. "go_tempate/config"
)

/*
  jwt创建token

  参数:
    Jwt:token结构体参数

  返回:
    1.jwt加密后的token字符串
    2.错误信息，如果没有错误返回nil
*/
// ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
func JwtCreateToken(Jwt *JwtToken) (string, error) {
	// 创建token,使用指定的secret签名并获得完整的编码后的字符串token
	//----------------------------------------------------------------------------------------------------------
	return jwt.NewWithClaims(jwt.SigningMethodHS256, Jwt).SignedString(JwtCreateTokenKey)

}

/*
  jwt解析token函数

  参数:
     encryption:jwt加密后的字符串

  返回:
    1.jwt解密后的token结构体
    2.错误的状态值，如果是-1则是解析成功，否则是对应的错误状态值
*/
// ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
func JwtParentToken(encryption string) (*JwtToken, int) {
	//如果传入的是空解析
	//----------------------------------------------------------------------------------------------------------
	if encryption == "" {
		return nil, -1
	}

	// 调用解析函数
	//----------------------------------------------------------------------------------------------------------
	token, err := jwt.ParseWithClaims(encryption, &JwtToken{}, func(token *jwt.Token) (interface{}, error) {
		// 只返回加密的秘钥
		return JwtCreateTokenKey, nil
	})

	//如果报错，则根据错误类型进行返回对应状态
	//----------------------------------------------------------------------------------------------------------
	if err != nil {
		if ve, ok := err.(*jwt.ValidationError); ok {
			if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
				// JWT尚未生效
				return nil, 2

			} else if ve.Errors&jwt.ValidationErrorSignatureInvalid != 0 {
				// JWT签名无效
				return nil, 3

			} else if ve.Errors&jwt.ValidationErrorMalformed != 0 {
				// JWT格式错误
				return nil, 4

			} else if ve.Errors&jwt.ValidationErrorIssuer != 0 {
				// JWT签发者无效
				return nil, 5

			} else if ve.Errors&jwt.ValidationErrorAudience != 0 {
				// JWT接收者无效
				return nil, 6

			}
		}
	}

	// 拿到 MyJwtToken 类型的结构
	// Claims 接口实现了 Valid() 方法， 对数据进行验证
	//----------------------------------------------------------------------------------------------------------
	if claims, ok := token.Claims.(*JwtToken); ok && token.Valid {
		//成功则返回对应结果和正确的状态
		return claims, -1
	} else {
		//错误也返回对应结果，但状态为对应错误状态
		return claims, 1
	}
}
